package com.yl.order.ui.dialog;

import android.content.DialogInterface;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.view.KeyEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;

import com.net.yl.ApiRepository;
import com.net.yl.entity.PayOrderEntity;
import com.net.yl.entity.PayResultEntity;
import com.yl.common.ui.BaseDialogFragment;
import com.yl.order.Constants;
import com.yl.order.R;
import com.yl.order.db.entity.OrderEntity;
import com.yl.order.db.entity.OrderGoodsEntity;
import com.yl.order.helper.ScanCodeHelper;
import com.yl.order.interfaces.Callback;
import com.yl.order.interfaces.OnScanGunCallback;
import com.yl.order.utils.QRUtils;
import com.yl.order.utils.SPUtils;


import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.TreeMap;

/**
 * create by cjx on 2024/6/12
 * desc:
 */
public class PayFragment extends BaseDialogFragment implements DialogInterface.OnKeyListener, OnScanGunCallback {

    private boolean scanGun = false;

    private String price;
    private OrderEntity orderEntity;
    private ArrayList<OrderGoodsEntity> orderGoodsList;
    private PayOrderEntity payOrderEntity;

    private boolean scanLock = false; // 锁住不接受扫码的内容
    private boolean querying = false;
    private boolean queryMode = false; //是否进入查询模式
    private boolean paySuccess = false; // 是否付款成功
    private int lastTime = 120;
    private Timer timer;
    private TimerTask timerTask;
    private TextView timeView;
    private ImageView codeView;
    private ProgressBar progressBar;

    private Callback<Integer> callback;
    private Callback<Boolean> dismissCallback;

    public static PayFragment newInstance(String price, OrderEntity orderEntity, ArrayList<OrderGoodsEntity> orderGoodsList) {
        PayFragment payFragment = new PayFragment();
        payFragment.price = price;
        payFragment.orderGoodsList = orderGoodsList;
        payFragment.orderEntity = orderEntity;
        payFragment.setCanceledOnTouchOutside(false);
        payFragment.saveStatusLog = false;
        return payFragment;
    }

    @Override
    public int getViewId() {
        return R.layout.fragment_pay;
    }

    @Override
    public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
        super.onViewCreated(view, savedInstanceState);
        timeView = findViewById(R.id.close);
        timeView.setOnClickListener(v -> {
            ConfirmDialogFragment.newInstance()
                    .setDescribe(getString(R.string.order_payment_cancel_tip))
                    .setConfirmCallback(i -> {
                        cancelPay();
                        dismiss();
                    })
                    .show(getChildFragmentManager(), "confirm");
        });
        startTimer();
        TextView titleView = findViewById(R.id.title);
        TextView priceView = findViewById(R.id.price);
        priceView.setText(String.format(getString(R.string.format_price), price));
        progressBar = findViewById(R.id.progress_bar);
        scanGun = SPUtils.getBoolean(Constants.SP_PAYMENT_SCAN_GUN, true);
        if (scanGun) {
            getDialog().setOnKeyListener(this);
            progressBar.setVisibility(View.GONE);
            titleView.setText(R.string.order_payment_gun);
            codeView = findViewById(R.id.pay_code);
            codeView.setImageResource(R.drawable.vector_scan_payment);
        } else {
            buildOrder(null);
            titleView.setText(R.string.order_payment_code);
            getPayCode();
        }

        ScanCodeHelper.getInstance().setScanGunCallback(this);
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        stopTime();
        if (dismissCallback != null) {
            dismissCallback.callback(paySuccess);
        }
    }

    @Override
    public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
        ScanCodeHelper.getInstance().parserKeyEvent(event);
        return true;
    }

    @Override
    public boolean scanResult(String code, String source) {
        scanCode(code);
        return false;
    }

    @Override
    protected float getDialogWidth() {
        return 0f;
    }

    private void buildOrder(String payCode) {
        List<TreeMap<String, Object>> collect = new ArrayList<>(orderGoodsList.size());
        for (OrderGoodsEntity o : orderGoodsList) {
            TreeMap<String, Object> orderDetail = new TreeMap<>();
            orderDetail.put("orderSubNo", o.getOrderSubNo());
            orderDetail.put("productName", o.getGoodsName());
            orderDetail.put("specName", o.getSpecName());
            orderDetail.put("price", o.getPrice());
            orderDetail.put("makeStatus", 1);
            collect.add(orderDetail);
        }
        payOrderEntity = new PayOrderEntity(orderEntity.getOrderNo(), orderEntity.getTotalAmount(), payCode, collect);
    }

    public void scanCode(String code) {
        if(scanLock){
            return;
        }
        progressBar.setVisibility(View.VISIBLE);
        codeView.setImageResource(0);
        scanLock = true;
        buildOrder(code);
        ApiRepository.getInstance().payWithCode(payOrderEntity, response -> {
            scanLock = false;
            if (getContext() == null) {
                return;
            }
            if (!response.isSuccess()) {
                progressBar.setVisibility(View.GONE);
                showToast(response.getMessage());
                codeView.setImageResource(R.drawable.vector_scan_payment);
                return;
            }
            if (response.getData()) {
                progressBar.setVisibility(View.GONE);
                paySuccess();
                return;
            }
            queryMode = true;
        }, throwable -> {
            scanLock = false;
            if (getContext() == null) {
                return;
            }
            progressBar.setVisibility(View.GONE);
            codeView.setImageResource(R.drawable.vector_scan_payment);
            showToast(throwable.getMessage());
        });
    }

    public PayFragment setPayCallback(Callback<Integer> callback) {
        this.callback = callback;
        return this;
    }

    public PayFragment setDismissCallback(Callback<Boolean> callback) {
        this.dismissCallback = callback;
        return this;
    }

    private void getPayCode() {
        ApiRepository.getInstance().createPayCode(payOrderEntity,
                response -> {
                    if (getContext() == null) {
                        return;
                    }
                    if (!response.isSuccess()) {
                        showToast(response.getMessage());
                        dismiss();
                        return;
                    }
                    queryMode = true;
                    showPayCode(response.getData().payUrl);
                }, throwable -> {
                    if (getContext() == null) {
                        return;
                    }
                    showToast(throwable.getMessage());
                    dismiss();
                });
    }

    private void showPayCode(String content) {
        progressBar.setVisibility(View.GONE);
        ImageView imageView = findViewById(R.id.pay_code);
        imageView.post(() -> QRUtils.createQRCodeBitmap(imageView, content));
    }

    private void startTimer() {
        stopTime();
        timer = new Timer(true);
        timerTask = new TimerTask() {
            @Override
            public void run() {
                lastTime--;
                if (lastTime < 0) {
                    cancelPay();
                    dismiss();
                    return;
                }
                if (lastTime % 3 == 0 && !querying && queryMode) {
                    queryPayStatus();
                }
                timeView.post(() -> timeView.setText(String.format(getString(R.string.order_payment_lasttime_format), lastTime)));
            }
        };
        timer.schedule(timerTask, 0, 1000);
    }

    private void stopTime() {
        if (timer != null) {
            timerTask.cancel();
            timer.cancel();
        }
    }

    private void queryPayStatus() {
        querying = true;
        ApiRepository.getInstance().queryPayStatus(orderEntity.getOrderNo(), response -> {
            querying = false;
            if (response.getData() != null && response.getData().status == PayResultEntity.STATUS_PAID) {
                paySuccess();
            }
        }, throwable -> {
            querying = false;
        });
    }

    private void paySuccess() {
        paySuccess = true;
        showToast(getString(R.string.order_payment_successful));
        dismiss();
        if (callback != null) {
            callback.callback(1);
        }
    }

    private void cancelPay() {
        if (orderEntity == null) {
            return;
        }
        ApiRepository.getInstance().closePay(orderEntity.getOrderNo(), r -> {

        }, t -> {

        });
    }

}
